home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 0.9.1.3 stable / flock-0.9.1.3.en-US.win32.exe / flock / components / flockSearchAPIFlock.js < prev    next >
Text File  |  2007-10-12  |  12KB  |  352 lines

  1. //
  2. // BEGIN FLOCK GPL
  3. // 
  4. // Copyright Flock Inc. 2005-2007
  5. // http://flock.com
  6. // 
  7. // This file may be used under the terms of of the
  8. // GNU General Public License Version 2 or later (the "GPL"),
  9. // http://www.gnu.org/licenses/gpl.html
  10. // 
  11. // Software distributed under the License is distributed on an "AS IS" basis,
  12. // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. // for the specific language governing rights and limitations under the
  14. // License.
  15. // 
  16. // END FLOCK GPL
  17. //
  18.  
  19. const CLASS_ID                = Components.ID("{C711A35C-8949-4D01-9676-47E71F1A78F4}");
  20. const CLASS_NAME              = "Flock Results Search Module";
  21. const CONTRACT_ID             = "@flock.com/flock-search-flock;1";
  22. const flockISearchService     = Components.interfaces.flockISearchService;
  23.  
  24. const FLOCK_NS = "http://flock.com/rdf#";
  25. const NC_NS = "http://home.netscape.com/NC-rdf#";
  26.  
  27. const RDFCU = Components.classes["@mozilla.org/rdf/container-utils;1"].getService(Components.interfaces.nsIRDFContainerUtils);
  28. const RDFS = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  29.  
  30. function flockSearchAPIFlock()
  31. {
  32.   this._favService = Components.classes["@mozilla.org/rdf/datasource;1?name=flock-favorites"].getService(Components.interfaces.nsIRDFDataSource);
  33.   this._logger = Components.classes["@flock.com/logger;1"].createInstance(Components.interfaces.flockILogger);
  34.   this._logger.init("search");
  35.   var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
  36.   var bundle = sbs.createBundle("chrome://flock/locale/search/search.properties");
  37.   this.serviceName = bundle.GetStringFromName("flock.search.api.flock");
  38. };
  39.  
  40. flockSearchAPIFlock.prototype = {
  41.  
  42.   _searchListener: null,
  43.   _maxResults: null,
  44.   _searchesOutstanding: null,
  45.   _resultsBookmarks: null,
  46.   _resultsHistory: null,
  47.   _currentQuery: null,
  48.   RDFS: null,
  49.   shortName: "flock",
  50.   icon: "rdf:http://flock.com/rdf#icon",
  51.   ref: "urn:flock:search:results",
  52.   mDS: null,
  53.   fullResultsUrl: "flock://search/?query=",
  54.  
  55.   search: function(aQuery, aNumResults, aListener, aDatasource)
  56.   {
  57.     this._searchListener = aListener;
  58.     this._maxResults = aNumResults;
  59.     
  60.     this._currentQuery = aQuery;
  61.     
  62.     // get references to the services we use
  63.     var searchService = Components.classes["@flock.com/lucene/flockLucene;1"].getService(Components.interfaces.flockILucene);
  64.     this.RDFS = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  65.     var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  66.     
  67.     // save a ref to the ds passed in
  68.     this.mDS = aDatasource;
  69.     
  70.     var normalizedQuery = this.normalizeQuery(aQuery);
  71.     
  72.     this._logger.debug("query: \"" + aQuery + "\" => \"" + normalizedQuery + "\"");
  73.     
  74.     var showHistory = prefService.getBoolPref("flock.search.flyout.showHistory") && prefService.getBoolPref("flock.service.indexer.indexWebHistory");
  75.     
  76.     // clear results
  77.     this._resultsBookmarks = [];
  78.     this._resultsHistory = [];
  79.     
  80.     // start the searchs
  81.     if (showHistory) {
  82.       this._searchesOutstanding = 2;
  83.       searchService.search(normalizedQuery, "bookmark", this._maxResults, this);
  84.       searchService.search(normalizedQuery, "history", this._maxResults, this);
  85.     } else {
  86.       this._searchesOutstanding = 1;
  87.       searchService.search(normalizedQuery, "bookmark", this._maxResults, this);
  88.     }
  89.   },
  90.   
  91.   normalizeQuery: function(input)
  92.   {
  93.     var output;
  94.     var in_quotes = false;
  95.  
  96.     // strip leading spaces
  97.     while (input.length && input[0]==" ") {
  98.       // chop off the first character
  99.       input = input.substr(1);
  100.     }
  101.  
  102.     // Convert to lowercase for the wildcard search
  103.     input = input.toLowerCase();
  104.   
  105.     // add leading plus
  106.     output = "+";
  107.     while (input.length) {
  108.       if (input[0] == "\"") {
  109.         if (in_quotes) {
  110.           in_quotes = false;
  111.         } else {
  112.           in_quotes = true;
  113.           // FIXME: remove spaces from the start of quoted strings
  114.         }
  115.       }
  116.  
  117.       // escape special chars
  118.       if ("&|!(){}[]^~*?:\\".indexOf(input[0]) >= 0) {
  119.         output = output + "\\";
  120.       }
  121.  
  122.       output = output + input[0];
  123.  
  124.       if (!in_quotes && input[0] == " " && input.length > 1) {
  125.           // put a plus before every word
  126.           output = output + "+";
  127.       }
  128.  
  129.       input = input.substr(1);
  130.     }
  131.  
  132.     // remove trailing spaces
  133.     var removed_spaces = false;
  134.     while (output.length > 0 && output[output.length - 1] == " ") {
  135.       output = output.substr(0, output.length - 1);
  136.       removed_spaces = true;
  137.     }
  138.  
  139.     // if we're in a quoted string we should close that
  140.     if (in_quotes) {
  141.       output = output + "\"";
  142.     }
  143.   
  144.     // if theres an incomplete word
  145.     if ((!removed_spaces) && (output[output.length - 1] != "\"")) {
  146.       // search for partial matches
  147.       output = output + "*";
  148.     }
  149.  
  150.     return output;
  151.   },
  152.   
  153.   // flockILuceneListener
  154.   onSearchComplete: function(aNumResults, aDataSource)
  155.   {
  156.     this._logger.debug("onSearchComplete: hits: " + aNumResults);
  157.     
  158.     if (aNumResults > 0) {
  159.         var root = this.RDFS.GetResource("urn:flock:search:results");
  160.         var container = Components.classes["@mozilla.org/rdf/container;1"].createInstance(Components.interfaces.nsIRDFContainer);
  161.         try {
  162.           container.Init(aDataSource, root);
  163.         } catch (ex) {}
  164.         
  165.         var results = container.GetElements();
  166.         
  167.         while (results.hasMoreElements()) {
  168.           var result = results.getNext();
  169.           result.QueryInterface(Components.interfaces.nsIRDFResource);
  170.           var uri = result.ValueUTF8;
  171.           var url = aDataSource.GetTarget(result, this.RDFS.GetResource(FLOCK_NS + "URL"), true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  172.           var type = aDataSource.GetTarget(result, this.RDFS.GetResource(FLOCK_NS + "type"), true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  173.           var title = aDataSource.GetTarget(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#Name"), true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  174.       
  175.           this._logger.debug("foundResults: " + type + " " + uri);
  176.           
  177.           switch(type) {
  178.             case "bookmark":
  179.               this._resultsBookmarks.push([url, title]);
  180.               break;
  181.             case "history":
  182.               this._resultsHistory.push([url, title]);
  183.               break;
  184.           }
  185.         }
  186.       }
  187.     
  188.     this._searchesOutstanding--;
  189.     
  190.     if (this._searchesOutstanding == 0) {
  191.       this._returnResults();
  192.     }
  193.   },
  194.   
  195.   _returnResults: function()
  196.   {
  197.     this._logger.debug("_returnResults");
  198.     
  199.     var resultSet = this.mDS;
  200.     var resultSetRoot = this.RDFS.GetResource("urn:flock:search:results");
  201.     var rootContainer = RDFCU.MakeSeq(resultSet, resultSetRoot);
  202.     
  203.     var c;
  204.     var urlHash = {};
  205.     var url;
  206.     var title;
  207.     var favicon;
  208.     var result;
  209.     var resultCount = 0;
  210.     
  211.     // return bookmark results
  212.     for (c = 0; c < this._resultsBookmarks.length && resultCount < this._maxResults; c++) {
  213.       url = this._resultsBookmarks[c][0];
  214.       title = this._resultsBookmarks[c][1];
  215.       favicon = "chrome://browser/skin/flock/search/documentIcon16.png";
  216.       infoicon = "chrome://browser/skin/flock/common/star16.png";
  217.       
  218.       // skip duplicate bookmarks (online bookmarks)
  219.       if (urlHash[url] == true) {
  220.         continue;
  221.       }
  222.  
  223.       urlHash[url] = true;
  224.       
  225.       result = this.RDFS.GetAnonymousResource();
  226.  
  227.       rootContainer.AppendElement(result);
  228.     
  229.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#URL"), this.RDFS.GetLiteral(url), true);
  230.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#Name"), this.RDFS.GetLiteral(title), true);
  231.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#favicon"), this.RDFS.GetLiteral(favicon), true);
  232.       resultSet.Assert(result, this.RDFS.GetResource(FLOCK_NS + "infoicon"), this.RDFS.GetLiteral(infoicon), true);
  233.       
  234.       resultCount++;
  235.     }
  236.     
  237.     // fill in history results
  238.     for (c = 0; c < this._resultsHistory.length && resultCount < this._maxResults; c++) {
  239.       url = this._resultsHistory[c][0];
  240.       title = this._resultsHistory[c][1];
  241.       favicon = "chrome://browser/skin/flock/search/documentIcon16.png";
  242.       
  243.       // skip history results that have already been returned as bookmarks
  244.       if (urlHash[url] == true) {
  245.         continue;
  246.       }
  247.       
  248.       result = this.RDFS.GetAnonymousResource();
  249.  
  250.       rootContainer.AppendElement(result);
  251.     
  252.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#URL"), this.RDFS.GetLiteral(url), true);
  253.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#Name"), this.RDFS.GetLiteral(title), true);
  254.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#favicon"), this.RDFS.GetLiteral(favicon), true);
  255.       
  256.       resultCount++;
  257.     }
  258.   
  259.     this._searchListener.foundResults(resultCount, resultSet, this.shortName, this._currentQuery);
  260.     // JMC - Trying to fix leak of this listener
  261.     this._searchListener = null;
  262.   },  
  263.   
  264.   // nsIClassInfo
  265.   getInterfaces: function(aCount)
  266.   {
  267.     var interfaces = [Components.interfaces.flockISearchService, Components.interfaces.nsIClassInfo, Components.interfaces.flockILuceneListener];
  268.     aCount.value = interfaces.length;
  269.     return interfaces;
  270.   },
  271.  
  272.   // nsIClassInfo
  273.   getHelperForLanguage: function(aLanguage)
  274.   {
  275.     return null;
  276.   },
  277.  
  278.   // nsIClassInfo
  279.   contractID: CONTRACT_ID,
  280.  
  281.   // nsIClassInfo
  282.   classDescription: CLASS_NAME,
  283.  
  284.   // nsIClassInfo
  285.   classID: CLASS_ID,
  286.  
  287.   // nsIClassInfo
  288.   implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
  289.  
  290.   // nsIClassInfo
  291.   flags: Components.interfaces.nsIClassInfo.SINGLETON,
  292.   
  293.   // nsISupports
  294.   QueryInterface: function(aIID)
  295.   {
  296.     if (!aIID.equals(Components.interfaces.nsISupports) && !aIID.equals(Components.interfaces.flockISearchService) && !aIID.equals(Components.interfaces.nsIClassInfo) && !aIID.equals(Components.interfaces.flockILuceneListener))
  297.       throw Components.results.NS_ERROR_NO_INTERFACE;
  298.     return this;
  299.   }
  300.  
  301. };
  302.  
  303. /******************************************************************************
  304.  * XPCOM Functions for construction and registration
  305.  ******************************************************************************/
  306. var Module = {
  307.   _firstTime: true,
  308.   registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
  309.   {
  310.     if (this._firstTime) {
  311.       this._firstTime = false;
  312.       throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  313.     }
  314.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  315.     aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
  316.     
  317.     // register search provider
  318.     var catmgr = Components.classes["@mozilla.org/categorymanager;1"]
  319.       .getService(Components.interfaces.nsICategoryManager);
  320.     catmgr.addCategoryEntry("flockISearchService", "flock", CONTRACT_ID, true, true);
  321.   },
  322.  
  323.   unregisterSelf: function(aCompMgr, aLocation, aType)
  324.   {
  325.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  326.     aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);        
  327.   },
  328.   
  329.   getClassObject: function(aCompMgr, aCID, aIID)
  330.   {
  331.     if (!aIID.equals(Components.interfaces.nsIFactory))
  332.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  333.     if (aCID.equals(CLASS_ID))
  334.       return Factory;
  335.     throw Components.results.NS_ERROR_NO_INTERFACE;
  336.   },
  337.  
  338.   canUnload: function(aCompMgr) { return true; }
  339. };
  340.  
  341. var Factory = {
  342.   createInstance: function(aOuter, aIID)
  343.   {
  344.     if (aOuter != null)
  345.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  346.     return (new flockSearchAPIFlock()).QueryInterface(aIID);
  347.   }
  348. };
  349.  
  350. function NSGetModule(aCompMgr, aFileSpec) { return Module; }
  351.  
  352.